#ifndef _IMAGE_OPERATION_H_
#define _IMAGE_OPERATION_H_

#include "Common.h"

#define HUE_RATIO (255.0 / 360.0)
#define NORMALIZE_HUE(h) ((BYTE) ((h) * HUE_RATIO + 0.05))

struct FindObject {
    int areaSize;   // 물체의 영역 크기
    int leftX;      // 영역의 제일 왼쪽 값
    int rightX;     // 영역의 제일 오른쪽 값
    int midX;     // 영역의 중간X 값
    int topY;     // 영역의 제일 위쪽 값
    int bottomY;    // 영역의 제일 아래쪽 값
    int midY;     // 영역의 중간Y 값
};

/* 확대, 축소해서 복사하기 */
void resizeImage(LPBYTE lpDest, CSize destSize, LPBYTE lpSrc, CSize srcSize, bool bSingleChannel = false);
void resizeImage(LPWORD lpDest, CSize destSize, LPWORD lpSrc, CSize srcSize, bool bSingleChannel = false);
int push(short *stackx, short *stacky, int arr_size, short vx, short vy, int *top);
int pop(short *stackx, short *stacky, short *vx, short *vy, int *top);
//int m_BlobColoring(unsigned char* CutImage, int height, int width);
void median_filtering();
unsigned char Sorting(LPBYTE Arr, int lenth);
void square(BYTE* img, int x1, int x2, int y1, int y2, int thick);
void circle2(BYTE* img, int x, int y, int rad, int thick, int r, int g, int b);
void cross(BYTE* img, int x, int y, int thick, int length, int r, int g, int b);
/* 1px당 1byte에서 3byte짜리 이미지로 복사 */
void copyWithExtension(LPBYTE lpDest, LPBYTE lpSrc, int width, int height);
/* hue 색상 360 -> 255 해상도로 낮춤 */
void normalizeHue(LPBYTE lpDest, LPWORD lpSrc, int width, int height);
/* AND 연산 */
void andOperator(LPBYTE lpResult, LPBYTE lpOp1, LPBYTE lpOp2, int width, int height);
/* OR 연산 */
void orOperator(LPBYTE lpResult, LPBYTE lpOp1, LPBYTE lpOp2, int width, int height);
/* OR 연산 || */
void orOperator(LPBYTE lpResult, LPBYTE lpOp1, LPBYTE lpOp2, LPBYTE lpOp3, int width, int height);
/* 뺄셈 연산 Mk.I  */
void subOperator(LPBYTE lpResult, LPBYTE lpOp1, LPBYTE lpOp2, int width, int height);
/* 뺄셈 연산 Mk.II */
void subAbsOperator(LPBYTE lpResult, LPBYTE lpOp1, LPBYTE lpOp2, int width, int height);
/* 뺄셈 연산 Mk.III */
void subAbsBinarization(LPBYTE lpResult, LPBYTE lpOp1, LPBYTE lpOp2, int width, int height, int thres);
void subAbsBinarization(LPWORD lpResult, LPWORD lpOp1, LPWORD lpOp2, int width, int height, int thres);
/* 이진화 */
void binarization(LPBYTE lpDest, LPBYTE lpSrc, int width, int height, int threshold);
/* 삼진화 */
void trinarization(LPBYTE lpDest, LPBYTE lpSrc, int width, int height, int thMin, int thMax);
void trinarization(LPWORD lpDest, LPWORD lpSrc, int width, int height, int thMin, int thMax);

void findVertex(LPBYTE lpImg, LPBYTE outImg, int x, int y, int rad, BYTE r, BYTE g, BYTE b);
void findVertex2(LPBYTE lpImg, LPBYTE outImg, int x, int y, int rad, BYTE r, BYTE g, BYTE b);
void drawRectangle(LPBYTE img, int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, int TH, BYTE r, BYTE g,
                   BYTE b);
void drawRectangle(LPBYTE img, int* x, int* y, int TH, BYTE r, BYTE g, BYTE b);
void vertex(LPBYTE lpImg, LPBYTE outImg, int imgH, int imgW, int fx, int fy);

void catImg(LPBYTE inImg, LPBYTE outImg);
void catColorImg(LPBYTE inImg, LPBYTE outImg, BYTE r, BYTE g, BYTE b);
void Bresenham(LPBYTE img, int x1, int y1, int const x2, int const y2, int thick, BYTE r, BYTE g, BYTE b);
void plot(int x, int y, int thick, LPBYTE img, BYTE r, BYTE g, BYTE b);

void labeling(int initx, int inity, int iHeight, int iWidth, LPBYTE labelNum, LPBYTE pImg);
int callLabel(int initx, int inity, int iHeight, int iWidth, LPBYTE pImg);
void processing(LPBYTE himg, LPBYTE edgeImg, LPBYTE output, Color color);

#endif
